package.path = "./?/init.lua;./dependencies/?.lua;"..package.path
require("lfs")
require("versium")
require("coroutine")

local v = versium.open{
   storage = "versium.storage.svn",
   params = {reposurl="file:///tmp/repostest", wc="/tmp/wctest"}
}

FOO = { 
   "Whose woods these are I think I know",
   "Whose woods these are I thought I knew"
}

FOO_DIFF = [[
  Whose
  _
  woods
  _
  these
  _
  are
  _
  I
  _
- think
+ thought
  _
  I
  _
- know
+ knew
  _
]]

BAR = {
   "Abracadabra",
   "Abracadabra2"
}

LUA = {
   [[
        x = 1
	y = 2
   ]],
   [[
        x = 1
	y = 4
   ]],

}

LUA_DIFF = [[
- 2
+ 4
  _
]]

function test_save_revision(id, value, author, comment, revid)
   return {
      text = "Save a new revision of "..id,
      f = function()
	     return v:save_version(id, value, author, comment)
	  end,
      expected = revid
   }
end

function check_cur_value(id, value)
   return {  
      text = "Check if we got the value of "..id.." right",
      f = function()
	     return v:get_node(id).data
	  end,
      expected = value
   }
end

function test_inflate_cur_value(id, field, value)
   return {
      text = "Inflate the latest version of "..id
	 .." and check the value of "..field,
      f = function()
	     local node = v:get_node(id)
	     inflated = v:inflate(node)
	     return inflated[field]
	  end,
      expected = value
   }
end

function test_inflated_metadata(id, field, value)
   return {
      text = "Inflate the latest version of "..id
	 .." and check the value of ._version."..field,
      f = function()
	     local node = v:get_node(id)
	     inflated = v:inflate(node)
	     return inflated._version[field]
	  end,
      expected = value
   }
end


function test_inflated_raw(id, value)
   return {
      text = "Inflate the latest version of "..id
	 .." and check the raw value.",
      f = function()
	     local node = v:get_node(id)
	     inflated = v:inflate(node)
	     return inflated._raw
	  end,
      expected = value
   }
end


function check_prev_value(id, value)
   return {  
      text = "Check the previous value of "..id,
      f = function()
	     rev_id = v:get_node_history(id)[2].version
	     return v:get_node(id, rev_id).data
	  end,
      expected = value
   }
end


function check_num_nodes(count)
   return {  
      text = "Check if we got "..tostring(count).." nodes in the repository",
      f = function()
	     return #v:get_node_ids()
	  end,
      expected = count
   }
end


function diff_to_string(diff)
   if not diff then return "" end
   local buffer = ""
   for i, token in ipairs(diff) do
      token[1] = string.gsub(token[1], "%s", "_")
      if token[2] == diff.SAME then
	 buffer = buffer.."  "..token[1].."\n"
      elseif token[2] == diff.IN then
	 buffer = buffer.."+ "..token[1].."\n"
      else
	 buffer = buffer.."- "..token[1].."\n"
      end
   end
   print(buffer)
   return buffer
end

function test_diff(id, v1, v2, diff)
   return {
      text = "Diff "..v1.." and "..v2.." of "..id,
      f = function()
	     return diff_to_string(v:diff(id, v1, v2))
	  end,
      expected = diff,
   }
end

function test_smart_diff(id, v1, v2, field, diff)
   return {
      text = "Smart-diff "..v1.." and "..v2.." of "..id,
      f = function()
	     return diff_to_string(v:smart_diff(id, v1, v2)[field])
	  end,
      expected = diff,
   }
end


tests = {
   check_num_nodes(0),

   test_save_revision("Foo", FOO[1], "yuri", "v1", "000001"),
   check_cur_value("Foo", FOO[1]),
   check_num_nodes(1),

   test_save_revision("Foo", FOO[2], "yuri", "v2", "000002"),
   check_cur_value("Foo", FOO[2]),
   check_prev_value("Foo", FOO[1]),
   check_num_nodes(1),

   test_save_revision("Bar", BAR[1], "andre", "v1", "000001"),
   check_cur_value("Bar", BAR[1]),
   check_num_nodes(2),

   test_save_revision("Lua", LUA[1], "yuri", "v1", "000001"),
   check_cur_value("Lua", LUA[1]),

   test_inflate_cur_value("Lua", "x", 1),
   test_inflate_cur_value("Lua", "y", 2),
   test_inflated_metadata("Lua", "author", "yuri"),
   test_inflated_raw("Lua", LUA[1]),

   test_diff("Foo", "000001", "000002", FOO_DIFF),
   
   test_save_revision("Lua", LUA[2], "yuri", "v2", "000002"),
   test_smart_diff("Lua", "000001", "000002", "y", LUA_DIFF),
}


for i, test in ipairs(tests) do

   print (test.text)
   local result = test.f()
   if (result == test.expected) then
      print ("ok\n")
   else
      print ("Whoops! Expected '"..tostring(test.expected)
	     .."' , got '"..tostring(result).."'")
   end

end

